"""
布局容器组件模块

提供了一系列布局容器组件，用于简化界面布局的创建和管理。
包括卡片容器、分组容器、水平布局容器、垂直布局容器和网格布局容器。
"""
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGridLayout, 
                            QLabel, QFrame, QSizePolicy, QScrollArea)
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QFont

from .theme import Theme


class Card(QFrame):
    """
    卡片容器组件
    
    一个带有阴影和边框的容器，可以包含任何组件。
    
    用法:
        card = Card("卡片标题")
        card.add_widget(widget)
        layout.addWidget(card)
    """
    
    def __init__(self, title=None, parent=None, shadow=True):
        """
        初始化卡片容器
        
        参数:
            title: 卡片标题，如果为None则不显示标题
            parent: 父组件
            shadow: 是否显示阴影
        """
        super().__init__(parent)
        
        # 设置框架样式
        self.setObjectName("card")
        self.setFrameShape(QFrame.StyledPanel)
        self.setFrameShadow(QFrame.Raised if shadow else QFrame.Plain)
        
        # 设置大小策略
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        
        # 创建主布局
        self.main_layout = QVBoxLayout(self)
        self.main_layout.setContentsMargins(15, 15, 15, 15)
        self.main_layout.setSpacing(10)
        
        # 添加标题（如果提供）
        if title:
            self.title_label = QLabel(title)
            self.title_label.setObjectName("card-title")
            self.title_label.setFont(QFont(Theme.FONT_FAMILY, Theme.FONT_SIZE_LARGE, QFont.Bold))
            self.main_layout.addWidget(self.title_label)
            
            # 添加一些间距
            self.main_layout.addSpacing(5)
        
        # 创建内容布局
        self.content_layout = QVBoxLayout()
        self.content_layout.setContentsMargins(0, 0, 0, 0)
        self.content_layout.setSpacing(10)
        
        self.main_layout.addLayout(self.content_layout)
        
        # 应用样式
        self._apply_style(shadow)
    
    def _apply_style(self, shadow):
        """应用样式"""
        # PyQt5不支持box-shadow，使用border和background-color模拟阴影效果
        shadow_style = ""
        if shadow:
            shadow_style = f"""
                border: 1px solid {Theme.BORDER_LIGHT};
                background-color: {Theme.BG_COLOR};
            """
        
        self.setStyleSheet(f"""
            QFrame#card {{
                background-color: {Theme.BG_COLOR};
                border: 1px solid {Theme.BORDER_LIGHT};
                border-radius: {Theme.BORDER_RADIUS_BASE}px;
                {shadow_style}
            }}
            
            QLabel#card-title {{
                color: {Theme.TEXT_PRIMARY};
                font-size: {Theme.FONT_SIZE_LARGE}px;
                font-weight: bold;
            }}
        """)
    
    def add_widget(self, widget):
        """添加组件到卡片内容区域"""
        self.content_layout.addWidget(widget)
    
    def add_layout(self, layout):
        """添加布局到卡片内容区域"""
        self.content_layout.addLayout(layout)
    
    def add_spacing(self, spacing):
        """添加间距到卡片内容区域"""
        self.content_layout.addSpacing(spacing)
    
    def add_stretch(self, stretch=1):
        """添加弹性空间到卡片内容区域"""
        self.content_layout.addStretch(stretch)


class Group(QWidget):
    """
    分组容器组件
    
    一个带有标题的分组容器，可以包含任何组件。
    
    用法:
        group = Group("分组标题")
        group.add_widget(widget)
        layout.addWidget(group)
    """
    
    def __init__(self, title, parent=None):
        """
        初始化分组容器
        
        参数:
            title: 分组标题
            parent: 父组件
        """
        super().__init__(parent)
        
        # 设置大小策略
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        
        # 创建主布局
        self.main_layout = QVBoxLayout(self)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(8)
        
        # 添加标题
        self.title_label = QLabel(title)
        self.title_label.setObjectName("group-title")
        self.title_label.setFont(QFont(Theme.FONT_FAMILY, Theme.FONT_SIZE_BASE, QFont.Bold))
        self.main_layout.addWidget(self.title_label)
        
        # 创建内容容器
        self.content_widget = QWidget()
        self.content_widget.setObjectName("group-content")
        
        # 创建内容布局
        self.content_layout = QVBoxLayout(self.content_widget)
        self.content_layout.setContentsMargins(10, 10, 10, 10)
        self.content_layout.setSpacing(10)
        
        self.main_layout.addWidget(self.content_widget)
        
        # 应用样式
        self._apply_style()
    
    def _apply_style(self):
        """应用样式"""
        self.setStyleSheet(f"""
            QLabel#group-title {{
                color: {Theme.TEXT_PRIMARY};
                font-size: {Theme.FONT_SIZE_BASE}px;
                font-weight: bold;
                padding-left: 2px;
            }}
            
            QWidget#group-content {{
                background-color: {Theme.BG_COLOR};
                border: 1px solid {Theme.BORDER_LIGHT};
                border-radius: {Theme.BORDER_RADIUS_BASE}px;
            }}
        """)
    
    def add_widget(self, widget):
        """添加组件到分组内容区域"""
        self.content_layout.addWidget(widget)
    
    def add_layout(self, layout):
        """添加布局到分组内容区域"""
        self.content_layout.addLayout(layout)
    
    def add_spacing(self, spacing):
        """添加间距到分组内容区域"""
        self.content_layout.addSpacing(spacing)
    
    def add_stretch(self, stretch=1):
        """添加弹性空间到分组内容区域"""
        self.content_layout.addStretch(stretch)


class HBox(QWidget):
    """
    水平布局容器组件
    
    一个水平布局的容器，可以包含任何组件。
    
    用法:
        hbox = HBox(margin=10, spacing=5)
        hbox.add_widget(widget)
        layout.addWidget(hbox)
    """
    
    def __init__(self, parent=None, margin=0, spacing=5, alignment=None):
        """
        初始化水平布局容器
        
        参数:
            parent: 父组件
            margin: 边距
            spacing: 间距
            alignment: 对齐方式
        """
        super().__init__(parent)
        
        # 设置大小策略
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        
        # 创建布局
        self.layout = QHBoxLayout(self)
        self.layout.setContentsMargins(margin, margin, margin, margin)
        self.layout.setSpacing(spacing)
        
        # 设置对齐方式
        if alignment:
            self.layout.setAlignment(alignment)
    
    def add_widget(self, widget, stretch=0, alignment=None):
        """
        添加组件到水平布局
        
        参数:
            widget: 要添加的组件
            stretch: 拉伸因子
            alignment: 对齐方式
        """
        if alignment:
            self.layout.addWidget(widget, stretch, alignment)
        else:
            self.layout.addWidget(widget, stretch)
    
    def add_layout(self, layout, stretch=0):
        """
        添加布局到水平布局
        
        参数:
            layout: 要添加的布局
            stretch: 拉伸因子
        """
        self.layout.addLayout(layout, stretch)
    
    def add_spacing(self, spacing):
        """添加间距到水平布局"""
        self.layout.addSpacing(spacing)
    
    def add_stretch(self, stretch=1):
        """添加弹性空间到水平布局"""
        self.layout.addStretch(stretch)
    
    def set_spacing(self, spacing):
        """设置组件之间的间距"""
        self.layout.setSpacing(spacing)
    
    def set_margin(self, margin):
        """设置布局的边距"""
        self.layout.setContentsMargins(margin, margin, margin, margin)
    
    def set_alignment(self, alignment):
        """设置布局的对齐方式"""
        self.layout.setAlignment(alignment)


class VBox(QWidget):
    """
    垂直布局容器组件
    
    一个垂直布局的容器，可以包含任何组件。
    
    用法:
        vbox = VBox(margin=10, spacing=5)
        vbox.add_widget(widget)
        layout.addWidget(vbox)
    """
    
    def __init__(self, parent=None, margin=0, spacing=5, alignment=None):
        """
        初始化垂直布局容器
        
        参数:
            parent: 父组件
            margin: 边距
            spacing: 间距
            alignment: 对齐方式
        """
        super().__init__(parent)
        
        # 设置大小策略
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        
        # 创建布局
        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(margin, margin, margin, margin)
        self.layout.setSpacing(spacing)
        
        # 设置对齐方式
        if alignment:
            self.layout.setAlignment(alignment)
    
    def add_widget(self, widget, stretch=0, alignment=None):
        """
        添加组件到垂直布局
        
        参数:
            widget: 要添加的组件
            stretch: 拉伸因子
            alignment: 对齐方式
        """
        if alignment:
            self.layout.addWidget(widget, stretch, alignment)
        else:
            self.layout.addWidget(widget, stretch)
    
    def add_layout(self, layout, stretch=0):
        """
        添加布局到垂直布局
        
        参数:
            layout: 要添加的布局
            stretch: 拉伸因子
        """
        self.layout.addLayout(layout, stretch)
    
    def add_spacing(self, spacing):
        """添加间距到垂直布局"""
        self.layout.addSpacing(spacing)
    
    def add_stretch(self, stretch=1):
        """添加弹性空间到垂直布局"""
        self.layout.addStretch(stretch)
    
    def set_spacing(self, spacing):
        """设置组件之间的间距"""
        self.layout.setSpacing(spacing)
    
    def set_margin(self, margin):
        """设置布局的边距"""
        self.layout.setContentsMargins(margin, margin, margin, margin)
    
    def set_alignment(self, alignment):
        """设置布局的对齐方式"""
        self.layout.setAlignment(alignment)


class GridBox(QWidget):
    """
    网格布局容器组件
    
    一个网格布局的容器，可以包含任何组件。
    
    用法:
        grid = GridBox(margin=10, spacing=5)
        grid.add_widget(widget, row, column)
        layout.addWidget(grid)
    """
    
    def __init__(self, parent=None, margin=0, spacing=5):
        """
        初始化网格布局容器
        
        参数:
            parent: 父组件
            margin: 边距
            spacing: 间距
        """
        super().__init__(parent)
        
        # 设置大小策略
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        
        # 创建布局
        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(margin, margin, margin, margin)
        self.layout.setSpacing(spacing)
    
    def add_widget(self, widget, row, column, row_span=1, column_span=1, alignment=None):
        """
        添加组件到网格布局
        
        参数:
            widget: 要添加的组件
            row: 行索引
            column: 列索引
            row_span: 行跨度
            column_span: 列跨度
            alignment: 对齐方式
        """
        if alignment:
            self.layout.addWidget(widget, row, column, row_span, column_span, alignment)
        else:
            self.layout.addWidget(widget, row, column, row_span, column_span)
    
    def add_layout(self, layout, row, column, row_span=1, column_span=1):
        """
        添加布局到网格布局
        
        参数:
            layout: 要添加的布局
            row: 行索引
            column: 列索引
            row_span: 行跨度
            column_span: 列跨度
        """
        self.layout.addLayout(layout, row, column, row_span, column_span)
    
    def set_row_stretch(self, row, stretch):
        """设置行的拉伸因子"""
        self.layout.setRowStretch(row, stretch)
    
    def set_column_stretch(self, column, stretch):
        """设置列的拉伸因子"""
        self.layout.setColumnStretch(column, stretch)
    
    def set_spacing(self, spacing):
        """设置组件之间的间距"""
        self.layout.setSpacing(spacing)
    
    def set_margin(self, margin):
        """设置布局的边距"""
        self.layout.setContentsMargins(margin, margin, margin, margin)


class ScrollBox(QScrollArea):
    """
    滚动容器组件
    
    一个可滚动的容器，可以包含任何组件。
    
    用法:
        scroll = ScrollBox()
        scroll.set_widget(widget)
        layout.addWidget(scroll)
    """
    
    def __init__(self, parent=None, horizontal=True, vertical=True):
        """
        初始化滚动容器
        
        参数:
            parent: 父组件
            horizontal: 是否允许水平滚动
            vertical: 是否允许垂直滚动
        """
        super().__init__(parent)
        
        # 设置滚动条策略
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded if horizontal else Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded if vertical else Qt.ScrollBarAlwaysOff)
        
        # 设置框架样式
        self.setFrameShape(QFrame.NoFrame)
        
        # 设置大小策略
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        
        # 设置组件可调整大小
        self.setWidgetResizable(True)
        
        # 应用样式
        self._apply_style()
    
    def _apply_style(self):
        """应用样式"""
        self.setStyleSheet(f"""
            QScrollArea {{
                background-color: transparent;
                border: none;
            }}
            
            QScrollBar:vertical {{
                background-color: {Theme.BG_COLOR};
                width: 12px;
                margin: 0px;
            }}
            
            QScrollBar::handle:vertical {{
                background-color: {Theme.BORDER_BASE};
                min-height: 20px;
                border-radius: 6px;
            }}
            
            QScrollBar::handle:vertical:hover {{
                background-color: {Theme.BORDER_LIGHT};
            }}
            
            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {{
                height: 0px;
            }}
            
            QScrollBar:horizontal {{
                background-color: {Theme.BG_COLOR};
                height: 12px;
                margin: 0px;
            }}
            
            QScrollBar::handle:horizontal {{
                background-color: {Theme.BORDER_BASE};
                min-width: 20px;
                border-radius: 6px;
            }}
            
            QScrollBar::handle:horizontal:hover {{
                background-color: {Theme.BORDER_LIGHT};
            }}
            
            QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal {{
                width: 0px;
            }}
        """)
    
    def set_widget(self, widget):
        """设置滚动区域的组件"""
        self.setWidget(widget)
    
    def set_horizontal_scroll(self, enabled):
        """设置是否允许水平滚动"""
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded if enabled else Qt.ScrollBarAlwaysOff)
    
    def set_vertical_scroll(self, enabled):
        """设置是否允许垂直滚动"""
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded if enabled else Qt.ScrollBarAlwaysOff) 